package com.hk.web.core.advice;

import com.hk.commons.annotation.IPLimiting;
import com.hk.commons.eunms.SysCode;
import com.hk.commons.exceptions.WebException;
import com.hk.commons.redis.RedisUtil;
import com.hk.commons.utils.JacksonUtil;
import com.hk.commons.utils.ResponseRenderUtils;
import com.hk.commons.utils.WebUtil;
import com.hk.commons.vo.JsonResult;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Aspect
public class IPLimitingAspect {
    private static Logger logger = LoggerFactory.getLogger(IPLimitingAspect.class);

    private static final String IP_LIMITING_REDIS_PREFIX = "hk:limiting:";

    @Autowired
    private RedisUtil redisUtil;

    public static IPLimitingAspect instance = new IPLimitingAspect();

    private  IPLimitingAspect(){
    }
    public static IPLimitingAspect getInstance(){
        return instance;
    }

    //设置限流切入点
    @Pointcut("execution(public * *(..)) && @annotation(com.hk.commons.annotation.IPLimiting)")
    public void doIpLimitingPointcut(){
    }

    @Before("doIpLimitingPointcut()")
    public void befor(JoinPoint JoinPoint) throws WebException {
        MethodSignature signature = (MethodSignature) JoinPoint.getSignature();
        Method method = signature.getMethod();
        IPLimiting annotation = method.getAnnotation(IPLimiting.class);
        long unitTime = annotation.unitTime();//单位时间 s
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = WebUtil.getVisitorIP(request);
        ip = StringUtils.replaceChars(ip,":",",");
        String key = IP_LIMITING_REDIS_PREFIX+ip+":"+request.getRequestURI();
        //先获取redis key
        Object value = redisUtil.getValue(key);
        if (value == null){
          redisUtil.setObj(key,1,unitTime);
          return;
        }
        int redisCount = Integer.parseInt(value + "");
        int count = annotation.count();//次数
        if (redisCount >= count){
            //返回给前端
            logger.info("ip:{} 访问限流",ip);
            throw new WebException(SysCode.LIMITING_ERROR);
        }
        redisUtil.increment(key);

    }

}
